package com.example.concurrent.chapter17;

import com.example.concurrent.chapter05.Lock;

import java.util.List;
import java.util.concurrent.TimeoutException;

/**
 * @author Liuqz
 * @date 2018/11/26 23:43
 */

//ReadLock被设计为包可见
class ReadLock implements Lock {

    private final ReadWriteLockImpl readWriteLock;

    public ReadLock(ReadWriteLockImpl readWriteLock) {
        this.readWriteLock = readWriteLock;
    }

    @Override
    public void lock() throws InterruptedException {
        //使用Mutex作为锁
        synchronized (readWriteLock.getMUTEX()) {
            /**
             * 若此时有线程正在进行写操作,或者有写线程正在等待并且偏向写锁的标识为true时,
             * 就会无法获得锁,只能为挂起
             */
            while (readWriteLock.getWritingWriters() > 0 ||
                    (readWriteLock.getPerferWriter() && readWriteLock.getWaitingWriters() > 0)) {
                readWriteLock.getMUTEX().wait();
            }
            readWriteLock.incrementReadingReaders();
        }
    }

    @Override
    public void lock(long mills) throws InterruptedException, TimeoutException {

    }

    @Override
    public List<Thread> getBlockedThreads() {
        return null;
    }

    @Override
    public void unlock() {
        /**
         * 释放锁的过程就是使得当前reading的数量减一
         * 将perferWriter设置为true,可以使得writer线程获得更多的机会
         * 通知唤醒与Mutex关联monitor waitset中的线程
         */
        synchronized (readWriteLock.getMUTEX()) {
            readWriteLock.decrementReadingReaders();
            readWriteLock.changePrefer(true);
            readWriteLock.getMUTEX().notifyAll();
        }
    }

}
